class Solution {
public:
    vector<vector<string> > ret;
    
    void change(TreeNode* root,int l,int r,int dep){
        if(!root || l > r) return;
        
        int mid = l + (r - l) / 2;
        ret[dep][mid] = to_string(root->val);
        
        change(root->left,l,mid-1,dep+1);
        change(root->right,mid+1,r,dep+1);
    
    }
                                        
    int deep(TreeNode* root){
        if(!root) return 0;
        return 1 + max(deep(root->left),deep(root->right));
    }
                                        
    vector<vector<string>> printTree(TreeNode* root) {
        int m = deep(root);
        int n = pow(2,m)-1;
        ret.resize(m,vector<string>(n));
        int l = 0;
        int r = n-1;
        int mid = l + (r-l) / 2;
        ret[0][mid] = to_string(root->val);
        
        change(root->left,l,mid-1,1);
        change(root->right,mid+1,r,1);
        
        return ret;
    }
};
